package com.ushine.web.communication.des.android;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * @Author: yls
 * @Date 2022/5/6 11:12
 * @Description: AES加密工具类
 * @Version 1.0
 **/
public class NetworkAndroidAesUtils {
    private NetworkAndroidAesUtils() {

    }

    /**
     * 定义 aes 加密的key
     * 密钥  必须是16位, 自定义,
     * 如果不是16位, 则会出现InvalidKeyException: Illegal key size
     * 解决方案有两种：
     * 需要安装Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files(可以在Oracle下载).
     * 设置设置key的长度为16个字母和数字的字符窜（128 Bit/8=16字符）就不报错了。
     */
    /**
     * 定义加密的编码
     */
    private static final Charset CHARSET = StandardCharsets.UTF_8;

    /**
     * 偏移量
     */
    private static final String TRANS_FORM_ACTION = "AES/CBC/PKCS5Padding";

    /**
     * 算法名称
     */
    private static final String ALGORITHM = "AES";


    /**
     * 功能描述:
     * 〈生成随机偏移量〉
     *
     * @return : byte[] 返回字节数组
     * @author : yls
     * @date : 2022/5/6 13:12
     */
    public static String getIv() {
        SecureRandom random = new SecureRandom();
        byte[] byteIv = new byte[16];
        random.nextBytes(byteIv);
        return Base64AndroidUtils.byte2Base64(byteIv);
    }

    /**
     * 功能描述:
     * 〈 生成一个AES的key 〉
     *
     * @param length
     * @return : java.lang.String
     * @author : yls
     * @date : 2022/5/9 11:09
     * @throws Exception
     */
    public static String generateDesKey(int length) throws Exception {
        //实例化
        KeyGenerator kgen = null;
        kgen = KeyGenerator.getInstance("AES");
        //设置密钥长度
        kgen.init(length);
        //生成密钥
        SecretKey skey = kgen.generateKey();
        //返回密钥的字符串格式
        return Base64AndroidUtils.byte2Base64(skey.getEncoded());
    }

    /**
     * 功能描述:
     * 〈 获取iv器 〉
     *
     * @param ivStr iv的base64编码字符串
     * @return : javax.crypto.spec.IvParameterSpec
     * @author : yls
     * @date : 2022/5/6 13:18
     */
    public static IvParameterSpec getIvParameterSpec(String ivStr) throws IOException {
        return new IvParameterSpec(Base64AndroidUtils.base642Byte(ivStr));
    }

    /**
     * 功能描述:
     * 〈 加密 〉
     *
     * @param content 待加密的数据
     * @return : java.lang.String
     * @author : yls
     * @date : 2022/2/11 15:12
     */
    public static String encryptContent(String content, String key, String ivStr) {
        try {
            IvParameterSpec iv = getIvParameterSpec(ivStr);
            return encrypt(content, key, iv);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 功能描述:
     * 〈 解密 〉
     *
     * @param content 待解密的数据
     * @return : java.lang.String
     * @author : yls
     * @date : 2022/2/11 15:12
     */
    public static String decryptContent(String content, String key, String ivStr) {
        try {
            IvParameterSpec iv = getIvParameterSpec(ivStr);
            return decrypt(content, key,iv);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 功能描述:
     * 〈加密〉
     *
     * @param content 待加密的内容
     * @param key     秘钥
     * @return : java.lang.String
     * @author : yls
     * @date : 2022/2/11 15:16
     */
    private static String encrypt(String content, String key, IvParameterSpec iv)
            throws NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidAlgorithmParameterException, InvalidKeyException,
            BadPaddingException, IllegalBlockSizeException, IOException {
        SecretKeySpec skey = new SecretKeySpec(Base64AndroidUtils.base642Byte(key), ALGORITHM);
        Cipher cipher = Cipher.getInstance(TRANS_FORM_ACTION);
        byte[] byteContent = content.getBytes(CHARSET);
        // 初始化
        cipher.init(Cipher.ENCRYPT_MODE, skey, iv);
        byte[] result = cipher.doFinal(byteContent);
        // 加密
        return Base64AndroidUtils.byte2Base64(result);

    }

    /**
     * 功能描述:
     * 〈AES（256）解密〉
     *
     * @param content 待解密的内容
     * @param key     解密
     * @return : java.lang.String
     * @author : yls
     * @date : 2022/2/11 15:16
     */
    private static String decrypt(String content, String key,IvParameterSpec iv)
            throws NoSuchPaddingException, NoSuchAlgorithmException,
            BadPaddingException, IllegalBlockSizeException,
            InvalidAlgorithmParameterException, InvalidKeyException, IOException {
        SecretKeySpec skey = new SecretKeySpec(Base64AndroidUtils.base642Byte(key), ALGORITHM);
        Cipher cipher = Cipher.getInstance(TRANS_FORM_ACTION);
        // 初始化
        cipher.init(Cipher.DECRYPT_MODE, skey, iv);
        byte[] result = cipher.doFinal(Base64AndroidUtils.base642Byte(content));
        // 解密
        return new String(result, StandardCharsets.UTF_8);
    }

}
